﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TSL_Tools.SqlTools;
using System.IO;
using System.Data;

namespace VSLT_ReportingEngine
{
    public partial class ReportingEngine
    {
        public static string reportingEngineVersion = "6.0.0.1 Beta";
        public string sqlConnection
        {
            get { return Properties.Settings.Default.sqlConn; }
            set
            {
                if(value != null)
                {
                    Properties.Settings.Default.sqlConn = value;
                    Properties.Settings.Default.Save();
                }
            }
        }

        #region -- Private Properties ---------------------------------------------------
        TalkToSql tts;
        private static string Sql_QUERY_DELIMITER = "GO\r\n";
        private static string Sql_QUERY_SECTION_DELIMITER = "--START CODE--";
        #endregion

        #region -- Constructors ---------------------------------------------------------
        public ReportingEngine(string expectedReportingEngineVersion)
        {
            if (expectedReportingEngineVersion != reportingEngineVersion)
            {
                throw new NotSupportedException(String.Format("The version of the Reporting Engine DLL does not match the version of the Application calling it. This indicates that the code for the two applications are out of sync.\r\nReporting Engine Version: {0}\r\nApplication Version: {1}", reportingEngineVersion, expectedReportingEngineVersion));
            }
            sqlConnection = Properties.Settings.Default.sqlConn;
            tts = new TalkToSql(Properties.Settings.Default.sqlConn);
            minimumPointsForConstantInterval = 10;
            minimumSecondsForConstantInterval = 60;
        }

        public ReportingEngine(string sqlConn, string expectedReportingEngineVersion)
        {
            if (expectedReportingEngineVersion != reportingEngineVersion)
            {
                throw new NotSupportedException(String.Format("The version of the Reporting Engine DLL does not match the version of the Application calling it. This indicates that the code for the two applications are out of sync.\r\nReporting Engine Version: {0}\r\nApplication Version: {1}", reportingEngineVersion, expectedReportingEngineVersion));
            }
            sqlConnection = sqlConn;
            tts = new TalkToSql(Properties.Settings.Default.sqlConn);
            minimumPointsForConstantInterval = 10;
            minimumSecondsForConstantInterval = 60;
        }
        #endregion


        #region -- Public Methods -------------------------------------------------------
        public int CleanupOldSql(ref StringBuilder sb)
        {
            int iNumQueries = 0;

            #region Old Query Cleanup
            using (StreamReader sr = new StreamReader(Properties.Settings.Default.Sql_CleanupFileName))
            {
                string sFileContents = sr.ReadToEnd();
                if (sFileContents.Contains(Sql_QUERY_SECTION_DELIMITER))
                {
                    sFileContents = sFileContents.Substring(sFileContents.IndexOf(Sql_QUERY_SECTION_DELIMITER));
                    int x = 0;
                    foreach (string str in sFileContents.Split(new string[] { Sql_QUERY_SECTION_DELIMITER }, StringSplitOptions.RemoveEmptyEntries))
                    {
                        string sSqlCmd = str.Substring(0, str.IndexOf(Sql_QUERY_DELIMITER));
                        tts.ExecuteNoReturn(sSqlCmd);
                        x++;
                        //Track the items that were removed.
                        int iStart = sSqlCmd.IndexOf("\n");
                        int iEnd = sSqlCmd.IndexOf("\r\n", iStart);
                        if (iEnd > iStart)
                            sb.Append(sSqlCmd.Substring(iStart, iEnd - iStart));
                        else
                            sb.Append(sSqlCmd.Substring(iStart));
                    }
                    iNumQueries += x;
                }
            }
            #endregion

            sb.Append(String.Format("\r\n===== Executed {0} Cleanup Batches =====\r\n", iNumQueries));
            return iNumQueries;
        }

        public int AddNewSql(ref StringBuilder sb)
        {
            int iNumQueries = 0;

            #region Query Updates
            using (StreamReader sr = new StreamReader(Properties.Settings.Default.Sql_UpdateFileName))
            {
                string sFileContents = sr.ReadToEnd();
                if (sFileContents.Contains(Sql_QUERY_SECTION_DELIMITER))
                {
                    sFileContents = sFileContents.Substring(sFileContents.IndexOf(Sql_QUERY_SECTION_DELIMITER));
                    int x = 0;
                    foreach (string str in sFileContents.Split(new string[] { Sql_QUERY_SECTION_DELIMITER }, StringSplitOptions.RemoveEmptyEntries))
                    {
                        string sSqlCmd = str.Substring(0, str.IndexOf(Sql_QUERY_DELIMITER));
                        tts.ExecuteNoReturn(sSqlCmd);
                        x++;
                        int iStart = sSqlCmd.IndexOf("\r\n") + 2;
                        int iEnd = sSqlCmd.IndexOf("\r\n", iStart) + 2;
                        if (iEnd > iStart)
                            sb.Append(sSqlCmd.Substring(iStart, iEnd - iStart).TrimStart(' ','\t'));
                        else
                            sb.Append(sSqlCmd.Substring(iStart).TrimStart(' ','\t'));
                    }
                    iNumQueries += x;
                }
            }
            #endregion
            sb.Append(String.Format("===== Added or updated {0} objects =====\r\n", iNumQueries));
            return iNumQueries;
        }

        public string UpdateTheDataWarehouseTables()
        {
            int x;
            string sqlCmd = "EXEC VSLT_prc_UpdateLoadTestCoreInfoTable";
            tts.ExecuteAndReturnRowCount(sqlCmd, out x);

            int y = 0;
            sqlCmd = "SELECT cmptlevel from master.dbo.sysdatabases WHERE name = 'master'";
            Int16 ver;
            tts.ExecuteScalarInt16(sqlCmd, out ver);
            if (ver >= 110)
            {
                // Use the new way which lets SQL figure out the intervals
                sqlCmd = "EXEC VSLT_prc_UpdateLoadTestIntervalTable";
                tts.ExecuteAndReturnRowCount(sqlCmd, out y);
            }
            else
            {
                // Do it the old fashioned way
                AddConstantLoadIntervals(ref y);
            }
            return String.Format("Updated {0} records in CORE tables and {1} records in INTERVAL table.", x, y);
        }

        public bool GetReportingEngineVersion(string expectedVersion)
        {
            // Does the SPROC exist?
            string retVal;
            tts.ExecuteScalarString(@"SELECT name FROM sysobjects WHERE name = 'VSLT_prc_Get_TSL_Reporting_Version' AND type = 'P'", out retVal);
            if (retVal == "")
                return false;

            // Now get and compare the version.
            string sVersion;
            tts.ExecuteScalarString(@"EXEC VSLT_prc_Get_TSL_Reporting_Version", out sVersion);

            if (sVersion.ToLower() == expectedVersion.ToLower())
                return true;
            else
                return false;
        }

        public DataTable GetListOfCompletedRuns()
        {
            DataTable _table = new DataTable();
            string Sql_GETRUNSFORDATAGRID = @"
SELECT LoadTestRunId AS 'Run #', LoadTestName, StartTime, RunDuration, [Description], FLAG_LoadTestParsingFailed AS [ParsingFailed] 
FROM VSLT_View_LoadTestSummary WHERE Outcome != 'InProgress' ORDER BY LoadTestRunId DESC
";
            tts.ExecuteReaderTable(Sql_GETRUNSFORDATAGRID, out _table);
            return _table;
        }
        #endregion
    }
}
